﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Corina.Commands;
using Corina.Common;

namespace Corina.Cydee.Apphub.Viewmodels
{
    public class UserHypotaxisViewmodel : ViewmodelBase
    {
        public UserHypotaxisViewmodel()
        {
            UserClient.GetAllUserItemsCompleted += GetAllUserItemsCompleted;
            UserClient.GetHypotaxisCompleted += GetHypotaxisCompleted;
            UserClient.GetUnallocateUsersCompleted += GetUnallocateUsersCompleted;
            UserClient.UpdateHypotaxisCompleted += UpdateHypotaxisCompleted;
            if(DataContext.IsValid)
            {
                LoadUsers();
            }
        }

        private void UpdateHypotaxisCompleted(object sender, DataService.UpdateHypotaxisCompletedEventArgs e)
        {
            if(e.Error == null)
            {
                LoadSubusers();
            }
        }

        private void GetUnallocateUsersCompleted(object sender, DataService.GetUnallocateUsersCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.Result == Enumerations.ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects.AsEnumerable()
                                 select new
                                 {
                                     Id = t["Id"],
                                     Name = t["Name"],
                                     Account = t["Account"]
                                 });
                    var allitems = UnallocateCollection.Concat(items);
                    UnallocateCollection = new ObservableCollection<object>(allitems);
                }
            }
        }

        private void GetHypotaxisCompleted(object sender, DataService.GetHypotaxisCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.Result == Enumerations.ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects.AsEnumerable()
                                 select new
                                 {
                                     Id = t["Id"],
                                     Name = t["Name"],
                                     Account = t["Account"]
                                 });
                    var allitems = SubuserCollection.Concat(items);
                    SubuserCollection = new ObservableCollection<object>(allitems);
                    //ItemsCount = e.Result.TotalCount;
                }
            }
        }

        private void GetAllUserItemsCompleted(object sender, DataService.GetAllUserItemsCompletedEventArgs e)
        {
            if(e.Error == null)
            {
                if(e.Result.Result == Enumerations.ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects.AsEnumerable()
                                 select new
                                 {
                                     Id = t["Id"],
                                     Name = t["Name"],
                                     Account = t["Account"]
                                 });
                    UserCollection = new ObservableCollection<object>(items);
                    ItemsCount = e.Result.TotalCount;
                }
            }
        }

        protected void LoadUsers()
        {
            UserClient.GetAllUserItemsAsync(Account, Password, "", 1, 20);
        }

        protected void LoadUnallocateUsers()
        {
            UserClient.GetUnallocateUsersAsync(Account, Password, "", 1, 20);
        }

        protected void LoadSubusers()
        {
            UserClient.GetHypotaxisAsync(Account, Password, SelectedUserId, 1, 20);
        }

        #region Collection
        private ObservableCollection<object> _userCollection;
        public ObservableCollection<object> UserCollection
        {
            get { return _userCollection; }
            set
            {
                _userCollection = value;
                RaisePropertyChanged(() => UserCollection);
            }
        }

        private ObservableCollection<object> _subuserCollection = new ObservableCollection<object>();
        public ObservableCollection<object> SubuserCollection
        {
            get { return _subuserCollection; }
            set
            {
                _subuserCollection = value;
                RaisePropertyChanged(() => SubuserCollection);
                SelectedSubids.Clear();
                if (SubuserCollection.Count > 0)
                {
                    SelectedSubids.AddRange(SubuserCollection.Select(t => (int)GetObjectPropertyValue(t, "Id")));
                }
            }
        }

        private ObservableCollection<object> _unallocateCollection = new ObservableCollection<object>();
        public ObservableCollection<object> UnallocateCollection
        {
            get { return _unallocateCollection; }
            set
            {
                _unallocateCollection = value;
                RaisePropertyChanged(() => UnallocateCollection);
            }
        }
        #endregion

        #region Search
        private object _selectedUser;
        public object SelectedUser
        {
            get { return _selectedUser; }
            set
            {
                _selectedUser = value;
                RaisePropertyChanged(() => SelectedUser);
                RaisePropertyChanged(() => SelectedUserId);
                SubuserCollection.Clear();
                ShowAllocate = false;
                LoadSubusers();
            }
        }

        public int SelectedUserId
        {
            get
            {
                return SelectedUser == null ? 0 : (int)GetObjectPropertyValue(SelectedUser, "Id");
            }
        }
        #endregion

        #region Allocate
        private List<int> _selectedSubids = new List<int>();
        protected List<int> SelectedSubids
        {
            get { return _selectedSubids; }
            set
            {
                _selectedSubids = value;
                RaisePropertyChanged(() => SelectedSubids);
            }
        }

        private bool _showAllocate = false;
        public bool ShowAllocate
        {
            get { return _showAllocate; }
            set
            {
                _showAllocate = value;
                RaisePropertyChanged(() => ShowAllocate);
            }
        }
        #endregion

        #region Command
        public ICommand RemoveCommand
        {
            get
            {
                return new DelegateCommand(parameter =>
                {
                    object obj = SubuserCollection.First(t => GetObjectPropertyValue(t, "Id") == parameter);
                    UnallocateCollection.Add(obj);
                    SubuserCollection.Remove(obj);
                });
            }
        }

        public ICommand AddCommand
        {
            get
            {
                return new DelegateCommand(parameter =>
                {
                    object obj = UnallocateCollection.First(t => GetObjectPropertyValue(t, "Id") == parameter);
                    if ((int)parameter != SelectedUserId)
                    {
                        SubuserCollection.Add(obj);
                        UnallocateCollection.Remove(obj);
                    }
                });
            }
        }

        public ICommand ShowAllocateCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate {
                        UnallocateCollection.Clear();
                        ShowAllocate = true;
                        LoadUnallocateUsers();
                    }
                };
            }
        }

        public ICommand SubmitCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        List<int> ids = new List<int>();
                        SubuserCollection.ForEach(t => {
                            ids.Add((int)GetObjectPropertyValue(t, "Id"));
                        });

                        string idString = string.Join(",", ids);

                        UserClient.UpdateHypotaxisAsync(Account, Password, SelectedUserId, idString);
                    }
                };
            }
        }
        #endregion
    }
}
